#include <stl/set.h>
#include <standard/math.h>
#include "terrainheightdatacmd.h"
#include "editorscenemgr.h"
#include "terrain/terrainobject.h"
#include "terrain/terrainblock.h"

CTerrainHeightCmd::CTerrainHeightCmd( map<uint32, float> *pTerrainCellHeightInfoList ){
    CTerrainObject* _pTerrainObject = m_pSceneMgr->GetTerrainObject();
    map<uint32, float>::iterator it = pTerrainCellHeightInfoList->begin();
    map<uint32, float>::iterator it_end = pTerrainCellHeightInfoList->end();
    for(; it != it_end; it++){
        STerrainHeightCMDInfo _sTerrainHeightCMDInfo;
        uint32 _nKey = it.first();
        _sTerrainHeightCMDInfo.m_nX = HIWORD( _nKey );
        _sTerrainHeightCMDInfo.m_nY = LOWORD( _nKey );
        _sTerrainHeightCMDInfo.m_fOriginHeight = it.second();
        _sTerrainHeightCMDInfo.m_fNewHeight = 0.0f;
        m_vTerrainCellHeightInfoList.push_back( _sTerrainHeightCMDInfo );
    }
}
CTerrainHeightCmd::~CTerrainHeightCmd(){

}
void CTerrainHeightCmd::Init(){
    CTerrainObject* _pTerrainObject = m_pSceneMgr->GetTerrainObject();
    list< STerrainHeightCMDInfo >::iterator it = m_vTerrainCellHeightInfoList.begin();
    list< STerrainHeightCMDInfo >::iterator it_end = m_vTerrainCellHeightInfoList.end();
    for(; it != it_end; it++){
        STerrainHeightCMDInfo* _pTerrainHeightCMDInfo = &(*it);
        _pTerrainHeightCMDInfo->m_fNewHeight = _pTerrainObject->GetCellHeight( _pTerrainHeightCMDInfo->m_nX, _pTerrainHeightCMDInfo->m_nY );
    }
}
void CTerrainHeightCmd::Final(){

}
bool32 CTerrainHeightCmd::Redo(){
    CTerrainBlock* _vTerrainBlock[4];
    set<CTerrainBlock*> _vTerrainBlockList;
    CTerrainObject* _pTerrainObject = m_pSceneMgr->GetTerrainObject();
    list< STerrainHeightCMDInfo >::iterator it = m_vTerrainCellHeightInfoList.begin();
    list< STerrainHeightCMDInfo >::iterator it_end = m_vTerrainCellHeightInfoList.end();
    for(; it != it_end; it++){
        STerrainHeightCMDInfo* _pTerrainHeightCMDInfo = &(*it);
        _pTerrainObject->SetCellHeight( _pTerrainHeightCMDInfo->m_nX, _pTerrainHeightCMDInfo->m_nY, _pTerrainHeightCMDInfo->m_fNewHeight );
        int32 _nTerrainBlock = _pTerrainObject->GetCellBlock( _pTerrainHeightCMDInfo->m_nX, _pTerrainHeightCMDInfo->m_nY, _vTerrainBlock );
        for( int32 i= 0 ; i < _nTerrainBlock; i ++ ){
            _vTerrainBlockList.insert( _vTerrainBlock[i] );
        }
    }
    set< CTerrainBlock* >::iterator it0 = _vTerrainBlockList.begin();
    set< CTerrainBlock* >::iterator it0_end = _vTerrainBlockList.end();
    for (; it0 != it0_end; it0++) {
        CTerrainBlock* _pTerrainBlock = it0.first();
        _pTerrainBlock->UpdateGeometry();
    }

    return True;
}
bool32 CTerrainHeightCmd::Undo(){
    CTerrainBlock* _vTerrainBlock[4];
    set<CTerrainBlock*> _vTerrainBlockList;
    CTerrainObject* _pTerrainObject = m_pSceneMgr->GetTerrainObject();
    list< STerrainHeightCMDInfo >::iterator it = m_vTerrainCellHeightInfoList.begin();
    list< STerrainHeightCMDInfo >::iterator it_end = m_vTerrainCellHeightInfoList.end();
    for(; it != it_end; it++){
        STerrainHeightCMDInfo* _pTerrainHeightCMDInfo = &(*it);
        _pTerrainObject->SetCellHeight( _pTerrainHeightCMDInfo->m_nX, _pTerrainHeightCMDInfo->m_nY, _pTerrainHeightCMDInfo->m_fOriginHeight );
        int32 _nTerrainBlock = _pTerrainObject->GetCellBlock( _pTerrainHeightCMDInfo->m_nX, _pTerrainHeightCMDInfo->m_nY, _vTerrainBlock );
        for( int32 i = 0; i < _nTerrainBlock; i ++ ){
            _vTerrainBlockList.insert( _vTerrainBlock[i] );
        }
    }
    set< CTerrainBlock* >::iterator it0 = _vTerrainBlockList.begin();
    set< CTerrainBlock* >::iterator it0_end = _vTerrainBlockList.end();
    for (; it0 != it0_end; it0++) {
        CTerrainBlock* _pTerrainBlock = it0.first();
        _pTerrainBlock->UpdateGeometry();
    }
    return True;
}